// 评估每一步的权重值
const MAX = Infinity;
const SIZE = 15;

// 使用 Alpha-Beta 剪枝算法寻找最佳着法
export function findBestMove(chessBoard, maxDepth, aiPlayRole) {
  let bestMove = null;
  let bestValue = -Infinity;
  // 棋盘上可以放置棋子的点
  let possibleMoves = chessBoard.reduce((acc, cur, index) => {
    if (cur === "") {
      acc.push(index);
    }
    return acc;
  }, []);

  possibleMoves.forEach((move) => {
    // 做可能的移动,计算最大值
    let newGameState = JSON.parse(JSON.stringify(chessBoard));
    newGameState[move] = aiPlayRole;
    newGameState = newGameState.map((val, i) => {
      if (val === "front") {
        return 1;
      } else if (val === "back") {
        return -1;
      }
      return 0;
    });

    let value = alphaBeta(newGameState, maxDepth - 1, -Infinity, Infinity, aiPlayRole === "back");

    if (value > bestValue) {
      bestValue = value;
      bestMove = move;
    }
  });

  return bestMove;
}

function alphaBeta(newGameState, depth, alpha, beta, maximizingPlayer) {
  if (depth == 0) {
    // 搜索达到最大深度或游戏结束，返回评估值
    return getMark(newGameState);
  }

  let bestValue;

  if (maximizingPlayer) {
    bestValue = -Infinity;
    // for (let move of gameState.getPossibleMoves()) {
    //   let newGameState = gameState.makeMove(move);
    let value = alphaBeta(newGameState, depth - 1, alpha, beta, false);
    alpha = Math.max(alpha, value);
    // if (beta <= alpha) {
    //   // 剪枝
    //   break;
    // }
    bestValue = Math.max(bestValue, value);
    // }
  } else {
    bestValue = Infinity;
    // for (let move of gameState.getPossibleMoves()) {
    //   let newGameState = gameState.makeMove(move);
    let value = alphaBeta(newGameState, depth - 1, alpha, beta, true);
    beta = Math.min(beta, value);
    // if (beta <= alpha) {
    //   // 剪枝
    //   break;
    // }
    bestValue = Math.min(bestValue, value);
    // }
  }

  return bestValue;
}

// function getPossibleMoves() {
//   const emptySquares = []; // 存储所有空位坐标
//   // const directions = [
//   //   [-1, 0],
//   //   [1, 0],
//   //   [0, -1],
//   //   [0, 1],
//   //   [-1, -1],
//   //   [1, 1],
//   //   [-1, 1],
//   //   [1, -1],
//   // ]; // 棋子延伸方向

//   // 遍历棋盘找到所有空位
//   for (let row = 0; row < boardSize; row++) {
//     for (let col = 0; col < boardSize; col++) {
//       if (board[row][col] === EMPTY) {
//         // EMPTY 表示棋盘上的空位
//         emptySquares.push([row, col]);
//       }
//     }
//   }

//   // // 对每个空位，检查放置棋子后是否符合基本规则（不直接形成超过五个的连线）
//   // const possibleMoves = [];
//   // for (const square of emptySquares) {
//   //   const [row, col] = square;

//   //   // 这里只是一个简化的验证逻辑示例，实际实现可能会更复杂，需考虑已有棋型和预防非法形成五子
//   //   if (!this.wouldCreateImmediateWin(row, col)) {
//   //     possibleMoves.push(square);
//   //   }
//   // }

//   return possibleMoves;
// }

function getMark(chessBoard) {
  let res = 0;
  for (let i = 0; i < SIZE; ++i) {
    for (let j = 0; j < SIZE; ++j) {
      // 落子点棋子
      let placeChess = chessBoard[i * SIZE + j];
      // 棋盘上的落子点非空
      if (placeChess !== 0) {
        // 行
        // 标记两侧的封堵情况
        let isOneSideBlocked = true;
        let isOtherSideBlocked = true;

        let row = i;
        let col = j;
        let count = 1;

        // 在落子点的行方向上，向左遍历,寻找相同的棋子
        while (--col > 0 && chessBoard[row * SIZE + col] == placeChess) {
          ++count;
        }

        // 在落子点行方向上，向左遍历，遇到未落子点,说明左侧未被封堵
        if (col > 0 && chessBoard[row * SIZE + col] === 0) {
          isOneSideBlocked = false;
        }

        col = j;

        // 在行方向上，向右遍历,寻找同类棋子
        while (++col <= SIZE && chessBoard[row * SIZE + col] == placeChess) {
          ++count;
        }

        // 在行方向上，向右遍历遇到未落子点,说明右侧未被封堵
        if (col <= SIZE && chessBoard[row * SIZE + col] === 0) {
          isOtherSideBlocked = false;
        }

        // 左右方向都未被封堵
        if (isOneSideBlocked === false && isOtherSideBlocked === false) {
          res += placeChess * count * count;
        }
        // 左右两边有一边未被封堵
        else if (isOneSideBlocked === false || isOtherSideBlocked === false) {
          res += (placeChess * count * count) / 4;
        }

        // 说明在行方向上,一方已获胜
        if (count >= 5) {
          res = MAX * placeChess;
        }

        // 列
        row = i;
        col = j;
        count = 1;
        isOneSideBlocked = true;
        isOtherSideBlocked = true;

        // 在落子点的列方向上，向上遍历,寻找相同的棋子
        while (--row > 0 && chessBoard[row * SIZE + col] == placeChess) {
          ++count;
        }

        // 上边未被封堵
        if (row > 0 && chessBoard[row * SIZE + col] === 0) {
          isOneSideBlocked = false;
        }

        row = i;
        // 在落子点的列方向上，向下遍历,寻找相同的棋子
        while (++row <= SIZE && chessBoard[row * SIZE + col] == placeChess) {
          ++count;
        }

        // 下边未被封堵
        if (row <= SIZE && chessBoard[row * SIZE + col] === 0) {
          isOtherSideBlocked = false;
        }

        if (isOneSideBlocked === false && isOtherSideBlocked === false) {
          res += placeChess * count * count;
        } else if (isOneSideBlocked === false || isOtherSideBlocked === false) {
          res += (placeChess * count * count) / 4;
        }

        // 列方向上出现五子相连
        if (count >= 5) {
          res = MAX * placeChess;
        }

        // 左对角线
        row = i;
        col = j;
        count = 1;
        isOneSideBlocked = true;
        isOtherSideBlocked = true;

        // 在左上对角线上,寻找相同的棋子
        while (--col > 0 && --row > 0 && chessBoard[row * SIZE + col] == placeChess) {
          ++count;
        }

        // 左上对角未被封堵
        if (col > 0 && row > 0 && chessBoard[row * SIZE + col] === 0) {
          isOneSideBlocked = false;
        }

        row = i;
        col = j;
        // 在右下对角线上,寻找相同的棋子
        while (++col <= SIZE && ++row <= SIZE && chessBoard[row * SIZE + col] == placeChess) {
          ++count;
        }

        // 右下对角未被封堵
        if (col <= SIZE && row <= SIZE && chessBoard[row * SIZE + col] === 0) {
          isOtherSideBlocked = false;
        }

        if (isOneSideBlocked === false && isOtherSideBlocked === false) {
          res += placeChess * count * count;
        } else if (isOneSideBlocked === false || isOtherSideBlocked === false) {
          res += (placeChess * count * count) / 4;
        }
        if (count >= 5) {
          res = MAX * placeChess;
        }

        // 右对角线
        row = i;
        col = j;
        count = 1;
        isOneSideBlocked = true;
        isOtherSideBlocked = true;

        // 在左下对角线上,寻找相同的棋子
        while (++row <= SIZE && --col > 0 && chessBoard[row * SIZE + col] == placeChess) {
          ++count;
        }

        // 左下对角线未被封堵
        if (row <= SIZE && col > 0 && chessBoard[row * SIZE + col] === 0) {
          isOneSideBlocked = false;
        }

        row = i;
        col = j;
        // 在右上对角线上,寻找相同的棋子
        while (--row > 0 && ++col <= SIZE && chessBoard[row * SIZE + col] == placeChess) {
          ++count;
        }
        // 右上对角线未被封堵
        if (row > 0 && col <= SIZE && placeChess === 0) {
          isOtherSideBlocked = false;
        }

        if (isOneSideBlocked === false && isOtherSideBlocked === false) {
          res += placeChess * count * count;
        } else if (isOneSideBlocked === false || isOtherSideBlocked === false) {
          res += (placeChess * count * count) / 4;
        }

        if (count >= 5) {
          res = MAX * placeChess;
        }
      }
    }
  }
  return res;
}
